<?php

/**
 * 专题分类模块
 *
 * @author yanghongji
 * @time 2015-1-14
 */
class SpecialcategoryModel extends BaseModel
{

    public $table = 'special_category';
    public $prikey = 'cate_id';
    public $_name = 'specialcategory';
    public $expire = 3600;
    public $_relation = array(
        // 一个分类有多个子分类
        'has_specialcategory' => array(
            'model' => 'specialcategory',
            'type' => HAS_MANY,
            'foreign_key' => 'parent_id',
            'dependent' => true
        ),
        // 分类和商品是多对多的关系
        'has_goods' => array(
            'model' => 'goods',
            'type' => HAS_AND_BELONGS_TO_MANY,
            'middle_table' => 'special_category_goods',
            'foreign_key' => 'cate_id',
            'reverse' => 'belongs_to_specialcategory',
        ),
    );
    public $_autov = array(
        'cate_name' => array(
            'required' => true,
            'filter' => 'trim',
        ),
        'sort_order' => array(
            'filter' => 'intval',
        ),
    );

    /*
     * 判断名称是否唯一
     */

    public function unique($cate_name, $parent_id, $cate_id = 0)
    {
        $conditions = "parent_id = '$parent_id' AND cate_name = '$cate_name'";
        $cate_id && $conditions .= " AND cate_id <> '" . $cate_id . "'";
        return count($this->find(array('conditions' => $conditions))) == 0;
    }

    public function get_list($parent_id = -1, $shown = false, $cache = false)
    {
        $cacheServer = cache_server();
        $cacheKey = "get_list_" . $parent_id . $shown;
        $data = $cacheServer->hGet($this->_name, $cacheKey);

        if ($data === false || $cache === false)
        {
            $conditions = "1 = 1";
            $parent_id >= 0 && $conditions .= " AND parent_id = '$parent_id'";
            $shown && $conditions .= " AND is_show = 1";
            $data = $this->find(array(
                'conditions' => $conditions,
                'order' => 'sort_order DESC, cate_id',
            ));
            $cacheServer->hSet($this->_name, $cacheKey, $data, $this->expire);
        }

        return $data;
    }

    public function get_options($parent_id = -1, $shown = false, $cache = false)
    {
        $options = array();
        $rows = $this->get_list($parent_id, $shown, $cache);
        foreach ($rows as $row)
        {
            $options[$row['cate_id']] = $row['cate_name'];
        }

        return $options;
    }

    /**
     * 取得某分类的子孙分类id（包括自身id）
     *
     * @param   int     $id     分类id
     * @param   bool    $cached 是否缓存（缓存数据不包括不显示的分类，一般用于前台；非缓存数据包括不显示的分类，一般用于后台）
     * @return  array(1, 2, 3, ...)
     */
    public function get_descendant_ids($id, $cached = false)
    {
        $res = array($id);

        if ($cached)
        {
            $data = $this->_get_structured_data();
            if ($id > 0 && isset($data[$id]))
            {
                $i = 0;
                while ($i < count($res))
                {
                    $id = $res[$i];
                    $res = array_merge($res, $data[$id]['cids']);
                    $i++;
                }
            }
        }
        else
        {
            $cids = array($id);
            while (!empty($cids))
            {
                $sql = "SELECT cate_id FROM {$this->table} WHERE parent_id " . db_create_in($cids);
                $cids = $this->getCol($sql);
                $res = array_merge($res, $cids);
            }
        }

        return $res;
    }

    /**
     * 取得某分类的祖先分类（包括自身，按层级排序）
     *
     * @param   int     $id     分类id
     * @param   bool    $cached 是否缓存（缓存数据不包括不显示的分类，一般用于前台；非缓存数据包括不显示的分类，一般用于后台）
     * @return  array(
     *              array('cate_id' => 1, 'cate_name' => '数码产品'),
     *              array('cate_id' => 2, 'cate_name' => '手机'),
     *              ...
     *          )
     */
    public function get_ancestor($id, $cached = false)
    {
        $res = array();

        if ($cached)
        {
            $data = $this->_get_structured_data();
            if ($id > 0 && isset($data[$id]))
            {
                while ($id > 0)
                {
                    $res[] = array('cate_id' => $id, 'cate_name' => $data[$id]['name']);
                    $id = $data[$id]['pid'];
                }
            }
        }
        else
        {
            while ($id > 0)
            {
                $sql = "SELECT cate_id, cate_name, parent_id FROM {$this->table} WHERE cate_id = '$id'";

                $row = $this->getRow($sql);

                if ($row)
                {
                    $res[] = array('cate_id' => $row['cate_id'], 'cate_name' => $row['cate_name']);
                    $id = $row['parent_id'];
                }
                else
                {
                    $id = 0;
                }
            }
        }

        //  echo "aaa";die();

        return array_reverse($res);
    }

    /**
     * 取得结构化的分类数据（不包括不显示的分类，数据会缓存）
     *
     * @return array(
     *      0 => array(                             'cids' => array(1, 2, 3))
     *      1 => array('name' => 'abc', 'pid' => 0, 'cids' => array(2, 3, 4)),
     *      2 => array('name' => 'xyz', 'pid' => 1, 'cids' => array()
     * )
     *    分类id        分类名称             父分类id     子分类ids
     */
    private function _get_structured_data()
    {
        $cache_server = & cache_server();
        $key = 'specialcategory_get_structured_data';
        $data = $cache_server->hGet($this->_name, $key);
        if ($data === false)
        {
            $data = array(0 => array('cids' => array()));

            $cate_list = $this->get_list(-1, true);
            foreach ($cate_list as $id => $cate)
            {
                $data[$id] = array(
                    'name' => $cate['cate_name'],
                    'pid' => $cate['parent_id'],
                    'cids' => array()
                );
            }

            foreach ($cate_list as $id => $cate)
            {
                $pid = $cate['parent_id'];
                isset($data[$pid]) && $data[$pid]['cids'][] = $id;
            }

            $cache_server->hSet($this->_name, $key, $data, $this->expire);
        }

        return $data;
    }

    /**
     * 取得某分类的层级（从1开始算起）
     * 
     * @param   int     $id     分类id
     * @param   bool    $cached 是否缓存（缓存数据不包括不显示的分类，一般用于前台；非缓存数据包括不显示的分类，一般用于后台）
     * @return  int     层级     当分类不存在或不显示时返回false
     */
    public function get_layer($id, $cached = false)
    {
        $ancestor = $this->get_ancestor($id, $cached);
        if (empty($ancestor))
        {
            return false; //分类不存在或不显示
        }
        else
        {
            return count($ancestor);
        }
    }

    /**
     * 取得某分类的深度（没有子节点深度为1）
     * 
     * @param   int     $id     分类id（需保证是存在的）
     * @return  int     深度
     */
    public function get_depth($id)
    {
        $depth = 0;

        $pids = array($id);
        while ($pids)
        {
            $depth++;
            $sql = "SELECT cate_id FROM {$this->table} " . $this->_getConditions("parent_id " . db_create_in($pids));
            $pids = $this->getCol($sql);
        }

        return $depth;
    }

    public function get_goods_ids($cate_ids, $cache = false)
    {
        if (!is_array($cate_ids))
            $cate_ids = array($cate_ids);

        $cacheServer = cache_server();
        $key = "specialcategory_get_goods_ids_" . implode("_", $cate_ids);
        $goods_ids = $cacheServer->hGet($this->_name, $key);
        if ($goods_ids === false || $cache === false)
        {
            $sql = "SELECT goods_id FROM ".DB_PREFIX."special_category_goods where  " . db_create_in($cate_ids, 'cate_id');
            $goods_ids = $this->getCol($sql);
            $cacheServer->hSet($this->_name, $key, $goods_ids, $this->expire);
        }

        return $goods_ids;
    }

    public function clear_cache()
    {
        $cacheServer = cache_server();
        $cacheServer->delete($this->_name);
    }

}
